Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / tests / backend / test_markdown_renderer.py

Displaying Raw • Download


tests/backend/test_markdown_renderer.py e5756d7ab065475a18acdcafc008a767fcff87e0 (e5756d7a) Text, 9.45 KB

T8b949e# SPDX-License-Identifier: 0BSD

Tff7b72import T7ee787time
Tff7b72import T7ee787unittest

Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787markdown_renderer Tff7b72import Te6edf3MarkdownRenderer


Tff7b72class T56d364TestMarkdownRendererTb4b4b4(Te6edf3unittestTff7b72.Td2a8ffTestCaseTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8fftest_basic_renderTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff<h1Ta5d6ff"Tb4b4b4, Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff# HelloTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffHelloTa5d6ff"Tb4b4b4, Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff# HelloTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff<strong>Bold</strong>Ta5d6ff"Tb4b4b4, Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff**Bold**Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff<em>Italic</em>Ta5d6ff"Tb4b4b4, Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff*Italic*Ta5d6ff"Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8fftest_headings_receive_stable_idsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff## First sectionTffea00\nTffea00\nTa5d6ff### Sub sectionTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff'Ta5d6ffid=Ta5d6ff"Ta5d6fffirst-sectionTa5d6ff"Ta5d6ff'Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff'Ta5d6ffid=Ta5d6ff"Ta5d6ffsub-sectionTa5d6ff"Ta5d6ff'Tb4b4b4, Te6edf3renderedTb4b4b4)

Tff7b72def Td2a8fftest_tables_render_as_htmlTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3md Tff7b72= Tb4b4b4(
Ta5d6ff"Ta5d6ff| Area | Route |Tffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ff| ---- | ----- |Tffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ff| Messages | /messages |Tffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ff| Map | /map |Tffea00\nTa5d6ff"
Tb4b4b4)
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3mdTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff<tableTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff<thTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffMessagesTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff/messagesTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff| Messages |Ta5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)

Tff7b72def Td2a8fftest_linksTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff[Google](https://google.com)Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff'Ta5d6ffhref=Ta5d6ff"Ta5d6ffhttps://google.comTa5d6ff"Ta5d6ff'Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffGoogleTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)

Tff7b72def Td2a8fftest_code_blocksTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3code Tff7b72= Ta5d6ff"Ta5d6ff```pythonTffea00\nTa5d6ffprint(Ta5d6ff'Ta5d6ffhelloTa5d6ff'Ta5d6ff)Tffea00\nTa5d6ff```Ta5d6ff"
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3codeTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff<preTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff<codeTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6fflanguage-pythonTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertTrueTb4b4b4(
Ta5d6ff"Ta5d6ffprint(&#x27;hello&#x27;)Ta5d6ff" Tff7b72in Te6edf3rendered
Tff7b72or Ta5d6ff"Ta5d6ffprint(&#039;hello&#039;)Ta5d6ff" Tff7b72in Te6edf3renderedTb4b4b4,
Tb4b4b4)

Tff7b72def Td2a8fftest_inline_code_before_underscore_italicTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ffUses `local_hops_delta` and ``rpc_key``.Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6fflocal_hops_deltaTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffrpc_keyTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff<em>hops</em>Ta5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff<em>key</em>Ta5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)

Tff7b72def Td2a8fftest_intraword_underscores_not_italicTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ffsnake_case_identifier stays plainTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffsnake_case_identifier stays plainTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff<em>Ta5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)

Tff7b72def Td2a8fftest_changelog_markdown_balanced_tagsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72from T7ee787pathlib Tff7b72import Te6edf3Path

Te6edf3changelog Tff7b72= Te6edf3PathTb4b4b4(Tff7b72__file__Tb4b4b4)Tff7b72.Td2a8ffresolveTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffparentsTb4b4b4[T79c0ff2Tb4b4b4] Tff7b72/ Ta5d6ff"Ta5d6ffCHANGELOG.mdTa5d6ff"
Tff7b72if Tff7b72not Te6edf3changelogTff7b72.Td2a8ffis_fileTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffskipTestTb4b4b4(Ta5d6ff"Ta5d6ffCHANGELOG.md not presentTa5d6ff"Tb4b4b4)
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3changelogTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff[[CBTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff[[ICTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3renderedTff7b72.Td2a8ffcountTb4b4b4(Ta5d6ff"Ta5d6ff<em>Ta5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3renderedTff7b72.Td2a8ffcountTb4b4b4(Ta5d6ff"Ta5d6ff</em>Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3renderedTff7b72.Td2a8ffcountTb4b4b4(Ta5d6ff"Ta5d6ff<strong>Ta5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3renderedTff7b72.Td2a8ffcountTb4b4b4(Ta5d6ff"Ta5d6ff</strong>Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3renderedTff7b72.Td2a8ffcountTb4b4b4(Ta5d6ff"Ta5d6ff<codeTa5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3renderedTff7b72.Td2a8ffcountTb4b4b4(Ta5d6ff"Ta5d6ff</code>Ta5d6ff"Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8fftest_listsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3md Tff7b72= Ta5d6ff"Ta5d6ff* Item 1Tffea00\nTa5d6ff* Item 2Ta5d6ff"
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3mdTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff<ulTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffItem 1Ta5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffItem 2Ta5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)

Tff7b72def Td2a8fftest_ordered_listsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3md Tff7b72= Ta5d6ff"Ta5d6ff1. FirstTffea00\nTa5d6ff2. SecondTa5d6ff"
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3mdTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff<olTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffFirstTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)

Tff7b72def Td2a8fftest_hrTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3md Tff7b72= Ta5d6ff"Ta5d6ff---Ta5d6ff"
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3mdTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff<hrTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)

Tff7b72def Td2a8fftest_task_listsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3md Tff7b72= Ta5d6ff"Ta5d6ff- [ ] Task 1Tffea00\nTa5d6ff- [x] Task 2Ta5d6ff"
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3mdTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff'Ta5d6fftype=Ta5d6ff"Ta5d6ffcheckboxTa5d6ff"Ta5d6ff'Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffcheckedTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffTask 1Ta5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffTask 2Ta5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)

Tff7b72def Td2a8fftest_strikethroughTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3md Tff7b72= Ta5d6ff"Ta5d6ff~~strike~~Ta5d6ff"
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3mdTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff<del>Ta5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffstrikeTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)

Tff7b72def Td2a8fftest_paragraphsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3md Tff7b72= Ta5d6ff"Ta5d6ffPara 1Tffea00\nTffea00\nTa5d6ffPara 2Ta5d6ff"
Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3mdTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff<pTa5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffPara 1Ta5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffPara 2Ta5d6ff"Tb4b4b4, Te6edf3renderedTb4b4b4)

Tff7b72def Td2a8fftest_render_none_and_emptyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Tff7b72NoneTb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertIsInstanceTb4b4b4(Te6edf3rTb4b4b4, Tffa657strTb4b4b4)

Tff7b72def Td2a8fftest_xss_script_tagsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3cases Tff7b72= Tb4b4b4[
Ta5d6ff"Ta5d6ff<script>alert(1)</script>Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff<SCRIPT>alert(1)</SCRIPT>Ta5d6ff"Tb4b4b4,
Ta5d6ff'Ta5d6ff<script src=Ta5d6ff"Ta5d6ffevil.jsTa5d6ff"Ta5d6ff></script>Ta5d6ff'Tb4b4b4,
Ta5d6ff"Ta5d6ff</script><script>alert(1)</script>Ta5d6ff"Tb4b4b4,
Tb4b4b4]
Tff7b72for Te6edf3s Tff7b72in Te6edf3casesTb4b4b4:
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3sTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff<script>Ta5d6ff"Tb4b4b4, Te6edf3rTb4b4b4, Te6edf3msgTff7b72=Te6edf3sTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff</script>Ta5d6ff"Tb4b4b4, Te6edf3rTb4b4b4, Te6edf3msgTff7b72=Te6edf3sTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff&lt;Ta5d6ff"Tb4b4b4, Te6edf3rTb4b4b4, Te6edf3msgTff7b72=Te6edf3sTb4b4b4)

Tff7b72def Td2a8fftest_xss_event_handlersTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3cases Tff7b72= Tb4b4b4[
Ta5d6ff'Ta5d6ff<img src=Ta5d6ff"Ta5d6ffxTa5d6ff"Ta5d6ff onerror=Ta5d6ff"Ta5d6ffalert(1)Ta5d6ff"Ta5d6ff>Ta5d6ff'Tb4b4b4,
Ta5d6ff'Ta5d6ff<body onload=Ta5d6ff"Ta5d6ffalert(1)Ta5d6ff"Ta5d6ff>Ta5d6ff'Tb4b4b4,
Ta5d6ff'Ta5d6ff<a href=Ta5d6ff"Ta5d6ffxTa5d6ff"Ta5d6ff onmouseover=Ta5d6ff"Ta5d6ffalert(1)Ta5d6ff"Ta5d6ff>x</a>Ta5d6ff'Tb4b4b4,
Ta5d6ff'Ta5d6ff<svg onload=Ta5d6ff"Ta5d6ffalert(1)Ta5d6ff"Ta5d6ff>Ta5d6ff'Tb4b4b4,
Tb4b4b4]
Tff7b72for Te6edf3s Tff7b72in Te6edf3casesTb4b4b4:
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3sTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff<imgTa5d6ff"Tb4b4b4, Te6edf3rTb4b4b4, Te6edf3msgTff7b72=Te6edf3sTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff<bodyTa5d6ff"Tb4b4b4, Te6edf3rTb4b4b4, Te6edf3msgTff7b72=Te6edf3sTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff<svgTa5d6ff"Tb4b4b4, Te6edf3rTb4b4b4, Te6edf3msgTff7b72=Te6edf3sTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff<a Ta5d6ff"Tb4b4b4, Te6edf3rTb4b4b4, Te6edf3msgTff7b72=Te6edf3sTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ff&lt;Ta5d6ff"Tb4b4b4, Te6edf3rTb4b4b4, Te6edf3msgTff7b72=Te6edf3sTb4b4b4)

Tff7b72def Td2a8fftest_xss_link_href_javascriptTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff[click](javascript:alert(1))Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ffjavascript:Ta5d6ff"Tb4b4b4, Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff'Ta5d6ffhref=Ta5d6ff"Ta5d6ff#Ta5d6ff"Ta5d6ff'Tb4b4b4, Te6edf3rTb4b4b4)

Tff7b72def Td2a8fftest_xss_link_href_dataTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff[click](data:text/html,<script>alert(1)</script>)Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ffdata:Ta5d6ff"Tb4b4b4, Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff'Ta5d6ffhref=Ta5d6ff"Ta5d6ff#Ta5d6ff"Ta5d6ff'Tb4b4b4, Te6edf3rTb4b4b4)

Tff7b72def Td2a8fftest_xss_link_href_vbscriptTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff[click](vbscript:msgbox(1))Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ffvbscript:Ta5d6ff"Tb4b4b4, Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff'Ta5d6ffhref=Ta5d6ff"Ta5d6ff#Ta5d6ff"Ta5d6ff'Tb4b4b4, Te6edf3rTb4b4b4)

Tff7b72def Td2a8fftest_protocol_relative_link_href_neutralizedTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff[phish](//evil.example/phish)Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff//evil.exampleTa5d6ff"Tb4b4b4, Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff'Ta5d6ffhref=Ta5d6ff"Ta5d6ff//Ta5d6ff'Tb4b4b4, Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff'Ta5d6ffhref=Ta5d6ff"Ta5d6ff#Ta5d6ff"Ta5d6ff'Tb4b4b4, Te6edf3rTb4b4b4)

Tff7b72def Td2a8fftest_unc_link_href_neutralizedTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3md Tff7b72= Ta5d6ff"Ta5d6ff[click](Ta5d6ff" Tff7b72+ Ta5d6ff"Tffea00\\Tffea00\\Tffea00\\Tffea00\\Ta5d6ffevil.exampleTffea00\\Tffea00\\Ta5d6ffshareTa5d6ff" Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3mdTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff'Ta5d6ffhref=Ta5d6ff"Ta5d6ff#Ta5d6ff"Ta5d6ff'Tb4b4b4, Te6edf3rTb4b4b4)

Tff7b72def Td2a8fftest_protocol_relative_image_src_neutralizedTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff![x](//evil.example/i)Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff//evil.exampleTa5d6ff"Tb4b4b4, Te6edf3rTb4b4b4)

Tff7b72def Td2a8fftest_safe_links_preservedTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff[link](https://example.com/path)Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff'Ta5d6ffhref=Ta5d6ff"Ta5d6ffhttps://example.com/pathTa5d6ff"Ta5d6ff'Tb4b4b4, Te6edf3rTb4b4b4)
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff[link](/relative)Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff'Ta5d6ffhref=Ta5d6ff"Ta5d6ff/relativeTa5d6ff"Ta5d6ff'Tb4b4b4, Te6edf3rTb4b4b4)
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff[link](#anchor)Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff'Ta5d6ffhref=Ta5d6ff"Ta5d6ff#anchorTa5d6ff"Ta5d6ff'Tb4b4b4, Te6edf3rTb4b4b4)

Tff7b72def Td2a8fftest_redos_safe_repeated_markersTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3t0 Tff7b72= Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4)
Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff*Ta5d6ff" Tff7b72* T79c0ff8000Tb4b4b4)
Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff#Ta5d6ff" Tff7b72* T79c0ff8000Tb4b4b4)
Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff`Ta5d6ff" Tff7b72* T79c0ff8000Tb4b4b4)
Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ff[](Ta5d6ff" Tff7b72* T79c0ff2000 Tff7b72+ Ta5d6ff"Ta5d6ffxTa5d6ff" Tff7b72* T79c0ff2000 Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff" Tff7b72* T79c0ff2000Tb4b4b4)
Te6edf3elapsed Tff7b72= Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3t0
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3elapsedTb4b4b4, T79c0ff2.0Tb4b4b4, Ta5d6ff"Ta5d6ffReDoS or excessive backtracking suspectedTa5d6ff"Tb4b4b4)

Tff7b72def Td2a8fftest_malformed_unclosed_markdownTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3cases Tff7b72= Tb4b4b4[
Ta5d6ff"Ta5d6ff**bold no closeTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff```Tffea00\nTa5d6ffcode no closeTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff*italicTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff`codeTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff___underTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff[unclosed link](urlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff![unclosed img](srcTa5d6ff"Tb4b4b4,
Tb4b4b4]
Tff7b72for Te6edf3s Tff7b72in Te6edf3casesTb4b4b4:
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3sTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertIsInstanceTb4b4b4(Te6edf3rTb4b4b4, Tffa657strTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff<script>Ta5d6ff"Tb4b4b4, Te6edf3rTb4b4b4)

Tff7b72def Td2a8fftest_very_long_inputTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3big Tff7b72= Ta5d6ff"Ta5d6ffxTa5d6ff" Tff7b72* Tb4b4b4(T79c0ff1024 Tff7b72* T79c0ff1024Tb4b4b4)
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3bigTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertIsInstanceTb4b4b4(Te6edf3rTb4b4b4, Tffa657strTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffxTa5d6ff"Tb4b4b4, Te6edf3rTb4b4b4)

Tff7b72def Td2a8fftest_unicode_and_control_charsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3cases Tff7b72= Tb4b4b4[
Ta5d6ff"Tffea00\x00Ta5d6ffhelloTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffhelloTffea00\x07Ta5d6ffworldTa5d6ff"Tb4b4b4,
Ta5d6ff"Tffea00\u202eTa5d6ffRTLTa5d6ff"Tb4b4b4,
Ta5d6ff"Tffea00\ufffdTa5d6ff replacementTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff# header Tffea00\nTa5d6ff normalTa5d6ff"Tb4b4b4,
Tb4b4b4]
Tff7b72for Te6edf3s Tff7b72in Te6edf3casesTb4b4b4:
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3sTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertIsInstanceTb4b4b4(Te6edf3rTb4b4b4, Tffa657strTb4b4b4)

Tff7b72def Td2a8fftest_render_returns_stringTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Ta5d6ff"Ta5d6ffHello **world**Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertIsInstanceTb4b4b4(Te6edf3rTb4b4b4, Tffa657strTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffHelloTa5d6ff"Tb4b4b4, Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertInTb4b4b4(Ta5d6ff"Ta5d6ffstrongTa5d6ff"Tb4b4b4, Te6edf3rTb4b4b4)

Tff7b72def Td2a8fftest_message_content_style_input_safeTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Simulate message body (e.g. decoded from LXMF) passed to render; must not crash or emit script."""
Te6edf3cases Tff7b72= Tb4b4b4[
Ta5d6ffbTa5d6ff"Ta5d6ffHello worldTa5d6ff"Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ffHi Tffea00\ufffdTa5d6ff replacement char Ta5d6ff" Tff7b72* T79c0ff10Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4,
Ta5d6ff"Tffea00\x00Tffea00\x01Tffea00\nTffea00\tTffea00\rTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff<script>alert(1)</script> normal textTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff**bold** and [link](javascript:x) endTa5d6ff"Tb4b4b4,
Ta5d6ff"Tffea00\u202eTa5d6ffRTL overrideTa5d6ff"Tb4b4b4,
Tb4b4b4]
Tff7b72for Te6edf3s Tff7b72in Te6edf3casesTb4b4b4:
Te6edf3r Tff7b72= Te6edf3MarkdownRendererTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3sTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertIsInstanceTb4b4b4(Te6edf3rTb4b4b4, Tffa657strTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ff<script>Ta5d6ff"Tb4b4b4, Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertNotInTb4b4b4(Ta5d6ff"Ta5d6ffjavascript:Ta5d6ff"Tb4b4b4, Te6edf3rTb4b4b4)


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────